﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#include "GnufDisplayAndPickFilterInitializer.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "IDocument.h"
#include "ICategoryAndGraphicsStyleFilter.h"
#include "UniIdentity.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

#define ICON_Annotation             L":/images/DisplayAndPickFilterTree/Annotation"
#define ICON_CadObject              L":/images/DisplayAndPickFilterTree/CadObject"
#define ICON_Constraint             L":/images/DisplayAndPickFilterTree/Constraint"
#define ICON_DrawingLine            L":/images/DisplayAndPickFilterTree/DrawingLine"
#define ICON_ElevationViewSymbol    L":/images/DisplayAndPickFilterTree/ElevationViewSymbol"
#define ICON_Form                   L":/images/DisplayAndPickFilterTree/Form"
#define ICON_InvisibleFormInProject L":/images/DisplayAndPickFilterTree/InvisibleFormInProject"
#define ICON_LineInstance           L":/images/DisplayAndPickFilterTree/LineInstance"
#define ICON_MepConnector           L":/images/DisplayAndPickFilterTree/MepConnector"
#define ICON_ModelLine              L":/images/DisplayAndPickFilterTree/ModelLine"
#define ICON_PlaneView              L":/images/DisplayAndPickFilterTree/PlaneView"
#define ICON_PointInstance          L":/images/DisplayAndPickFilterTree/PointInstance"
#define ICON_ReferenceLine          L":/images/DisplayAndPickFilterTree/ReferenceLine"
#define ICON_ReferencePlane         L":/images/DisplayAndPickFilterTree/ReferencePlane"
#define ICON_SectionViewSymbol      L":/images/DisplayAndPickFilterTree/SectionViewSymbol"
#define ICON_SketchCurve            L":/images/DisplayAndPickFilterTree/SketchCurve"
#define ICON_SkpObject              L":/images/DisplayAndPickFilterTree/SkpObject"
#define ICON_SubtractionForm        L":/images/DisplayAndPickFilterTree/SubtractionForm"
#define ICON_Text                   L":/images/DisplayAndPickFilterTree/Text"

using namespace gcmp;
using namespace gfam;

const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_POINT_FAMILY = GBMP_TR(L"点式构件");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_LINE_FAMILY = GBMP_TR(L"线式构件");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_PLANE = GBMP_TR(L"参照平面");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_LINE = GBMP_TR(L"参照线");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_SKETCH_LINE = GBMP_TR(L"草图线");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_DRAWING_LINE = GBMP_TR(L"二维线");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_DIMENSION_TEXT = GBMP_TR(L"文字");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_FAM_CONSTRAINT = GBMP_TR(L"构件约束");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_MEPCONNECTOR = GBMP_TR(L"机电连接件");
const static std::wstring COMPONENT_EDITOR_STYLE_GROUPNAME_FAMILYCONNECTOR = GBMP_TR(L"连接件");

const static std::wstring s_groupNamesInProject[] = {
    COMPONENT_EDITOR_STYLE_GROUPNAME_POINT_FAMILY,
    COMPONENT_EDITOR_STYLE_GROUPNAME_LINE_FAMILY,
    COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_PLANE,
    COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_LINE,
    COMPONENT_EDITOR_STYLE_GROUPNAME_SKETCH_LINE,
    COMPONENT_EDITOR_STYLE_GROUPNAME_DRAWING_LINE,
    COMPONENT_EDITOR_STYLE_GROUPNAME_DIMENSION_TEXT,
    COMPONENT_EDITOR_STYLE_GROUPNAME_FAM_CONSTRAINT,
    COMPONENT_EDITOR_STYLE_GROUPNAME_MEPCONNECTOR,
    COMPONENT_EDITOR_STYLE_GROUPNAME_FAMILYCONNECTOR
};

// tuple<uid, displayable, pickable>
// to config filterAuthority
typedef std::tuple<gcmp::UniIdentity, bool, bool> filterAuthority;
const static std::vector<filterAuthority> s_filter = {
    // 构件
    filterAuthority(BuiltInCategoryUniIdentities::BICU_POINT_FAMILY, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_LINE_FAMILY, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_REFERENCE_PLANE, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_REFERENCE_LINE, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_SKETCH_LINE, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_DRAWING_LINE, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_DIMENSION_TEXT, true, true),
    filterAuthority(BuiltInCategoryUniIdentities::BICU_FAM_CONSTRAINT, true, true),
};

typedef std::pair<UniIdentity, std::wstring> uid_icon;
static std::map<UniIdentity, std::wstring> s_icons = {
    uid_icon(BuiltInCategoryUniIdentities::BICU_POINT_FAMILY, ICON_PointInstance),
    uid_icon(BuiltInCategoryUniIdentities::BICU_LINE_FAMILY, ICON_LineInstance),
    uid_icon(BuiltInCategoryUniIdentities::BICU_REFERENCE_PLANE, ICON_ReferencePlane),
    uid_icon(BuiltInCategoryUniIdentities::BICU_REFERENCE_LINE, ICON_ReferenceLine),
    uid_icon(BuiltInCategoryUniIdentities::BICU_SKETCH_LINE, ICON_SketchCurve),
    uid_icon(BuiltInCategoryUniIdentities::BICU_DRAWING_LINE, ICON_DrawingLine),
    uid_icon(BuiltInCategoryUniIdentities::BICU_DIMENSION_TEXT, ICON_Text),
    uid_icon(BuiltInCategoryUniIdentities::BICU_FAM_CONSTRAINT, ICON_Constraint),
};

std::vector<UniIdentity> DisplayAndPickFilterInitializer::GetCategories(const IDocument* pDocument) const
{
    std::vector<UniIdentity> categories;
    DBG_WARN_AND_RETURN_UNLESS(pDocument, categories, L"pDocument指针为空，不合法", L"paramodel", L"2024-02-20");

    const ICategoryAndGraphicsStyleFilter* pICategoryAndGraphicsStyleFilter = ICategoryAndGraphicsStyleFilter::GetCategoryAndGraphicsStyleFilter();
    DBG_WARN_AND_RETURN_UNLESS(pICategoryAndGraphicsStyleFilter, categories, L"pICategoryAndGraphicsStyleFilter为空", L"paramodel", L"2024-02-20");
    categories = pICategoryAndGraphicsStyleFilter->GetCategoriesForObjectStyleSetting(pDocument);
    return categories;
}

std::vector<gcmp::UniIdentity> DisplayAndPickFilterInitializer::GetDefaultCannotBePickedCategories() const
{
    std::vector<gcmp::UniIdentity> categories;
    return categories;
}

std::vector<std::wstring> DisplayAndPickFilterInitializer::GetAllGroups(const gcmp::IDocument* pDocument) const
{
    std::vector<std::wstring> allGroups;
    DBG_WARN_AND_RETURN_UNLESS(pDocument, allGroups, L"pDocument指针为空，不合法", L"paramodel", L"2024-02-20");

    FOR_EACH(groupName, s_groupNamesInProject)
    {
        allGroups.emplace_back(groupName);
    }

    return allGroups;
}

std::vector<gcmp::UniIdentity> DisplayAndPickFilterInitializer::GetCategoriesByGroupName(const std::wstring& groupName) const
{
    std::vector<UniIdentity> categories;
    {
        if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_POINT_FAMILY)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_POINT_FAMILY);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_LINE_FAMILY)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_LINE_FAMILY);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_PLANE)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_REFERENCE_PLANE);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_REFERENCE_LINE)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_REFERENCE_LINE);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_SKETCH_LINE)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_SKETCH_LINE);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_DRAWING_LINE)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_DRAWING_LINE);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_DIMENSION_TEXT)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_DIMENSION_TEXT);
        }
        else if (groupName == COMPONENT_EDITOR_STYLE_GROUPNAME_FAM_CONSTRAINT)
        {
            categories.emplace_back(gcmp::BuiltInCategoryUniIdentities::BICU_FAM_CONSTRAINT);
        }
        else
        {
            DBG_WARN(L"未知的分组名称", L"paramodel", L"2024-02-20");
        }
    }
    return categories;
}

std::vector<gcmp::UniIdentity> gfam::DisplayAndPickFilterInitializer::GetAllHasChildCategories(const gcmp::IDocument* pDocument) const
{
    std::vector<gcmp::UniIdentity> categories;
    return categories;
}

std::vector<gcmp::UniIdentity> gfam::DisplayAndPickFilterInitializer::GetCategoriesByCategory(const gcmp::UniIdentity& categroy) const
{
    std::vector<gcmp::UniIdentity> categories;
    return categories; 
}

std::wstring gfam::DisplayAndPickFilterInitializer::GetCategoryIcon(const gcmp::UniIdentity& categroy) const
{
    std::wstring str;
    auto it = s_icons.find(categroy);
    if (it != s_icons.end())
    {
        return it->second;
    }
    return str;
}

std::vector<std::wstring> gfam::DisplayAndPickFilterInitializer::GetAllCollaborationGroups(const gcmp::IDocument* pDocument) const
{
    std::vector<std::wstring> collaborationGroupNames = {};
    return collaborationGroupNames;
}

bool gfam::DisplayAndPickFilterInitializer::GetCollaborationSubTreeByGroupName(const std::wstring & groupName, gcmp::OwnerPtr<DataStandardTree>& opSubTree) const
{
    return false;
}
